/*
 * Copyright 2012-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package keter.sec.xss.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.UUID;

/**
 * 使用双提交（Double Submit Cookie）防范CSRF
 * https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Double_Submit_Cookie
 * * */
//@Controller
public class CsrfCookieController {

    @GetMapping("/csrf")
    @ResponseBody
    public String csrf(HttpServletRequest request, HttpServletResponse response) {
        String s = UUID.randomUUID().toString(); //生成一个随机值用于csrf_cookie
        s = request.getSession().getId();//或者干脆使用SessionID作为csrf_cookie
        Cookie cookie = new Cookie("csrf_cookie",s);
        response.addCookie(cookie);
        addAllowHeader(response);
        return s;
    }

    @PostMapping("/csrf/form")
    @ResponseBody
    public String xsspost(HttpServletRequest request, HttpServletResponse response){
        System.out.println("sid:" + request.getSession().getId());
        //如果不添加允许跨域，已被浏览器阻止访问！
        addAllowHeader(response);
        if(!compareTokenWithCsrfCookie(request)){
            response.setStatus(403);
            return "csrf_cookie_validate_error!";
        }
        return "form post ok!";
    }

    private boolean compareTokenWithCsrfCookie(HttpServletRequest request){
        String csrf_token = request.getParameter("csrf_token");
        Cookie[] cookies = request.getCookies();
        if(csrf_token==null || cookies==null){
            return false;
        }
        Cookie csrf_cookie = Arrays.stream(request.getCookies()).filter(x -> x!=null && x.getName().equals("csrf_cookie")).findFirst().get();
        System.out.println("csrf cookie: " + csrf_cookie.getValue());
        if(csrf_token.equals(csrf_cookie.getValue())){
            return true;
        }
        return false;
    }
    /**
     * 允许浏览器跨域Ajax
     *
     * @param response
     * @author gulixing@msn.com
     * @date 2016年12月28日
     */
    private void addAllowHeader(HttpServletResponse response) {
        response.addHeader("Access-Control-Allow-origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST");
    }
}